//设置全局超时
jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000;
//全局变量
var baseUrl = "http://127.0.0.1:2111";
var dataM;
var TEST_JASMINE = {
    ENCRYPT_KEY: "d76eac5278390994075b321d5956ff14",//加密密匙
};
//ajax跨域请求
var sendRequest = function (callbacks, configuration) {

    configuration.method = configuration.method || "post";
    configuration.headers = configuration.headers || {"Content-Type": "application/json"};
    configuration.encrypt = configuration.encrypt || true;
    configuration.key = configuration.key || TEST_JASMINE.ENCRYPT_KEY;
    configuration.remainingCallTime = configuration.remainingCallTime || 4000;
    $.ajax({
        url: "../SimpleRequest",
        contentType: "application/json",
        data: JSON.stringify(configuration),
        "Content-Type": "utf-8",
        type: "post",
        async: true,
        success: function (data, status, xhr) {
            console.log({url: configuration.url, data: configuration.data});
            console.log(data);
            callbacks(data, xhr, status);
        },
        error: function (xhr, status, err) {
            console.log({url: configuration.url, data: configuration.data});
            console.log(err);
            callbacks(err, xhr, status);
        },
        timeout: configuration.remainingCallTime ? configuration.remainingCallTime : 3000
    });
};
Date.prototype.Format = function (fmt) { //author: meizz
    var o = {
        "M+": this.getMonth() + 1,                 //月份
        "d+": this.getDate(),                    //日
        "h+": this.getHours(),                   //小时
        "m+": this.getMinutes(),                 //分
        "s+": this.getSeconds(),                 //秒
        "q+": Math.floor((this.getMonth() + 3) / 3), //季度
        "S": this.getMilliseconds()             //毫秒
    };
    if (/(y+)/.test(fmt))
        fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
    for (var k in o)
        if (new RegExp("(" + k + ")").test(fmt))
            fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
    return fmt;
}
var getUniqueId = (function () {
    var i = 0;
    return function (string) {
        return new Date(Date.now()).Format(string || "yyMMddhhmms") + i++;
    }
})();
function changeData(origin, toChange, remove, notDeepClone) {
    if (typeof origin != 'object')
        throw 'changeData need (@object,object,array)!'
    if (!notDeepClone)
        origin = JSON.parse(JSON.stringify(origin));
    if (toChange) {
        for (var key in toChange) {
            var keys = key.split('.');
            for (var i = 0, now = origin; i < keys.length - 1; i++) {
                if (typeof now[keys[i]] != 'object')
                    now[keys[i]] = {};
                now = now[keys[i]];
            }
            now[keys[i]] = toChange[key];
        }
    }
    if (remove) {
        remove.forEach(function (key) {
            var keys = key.split('.');
            for (var i = 0, now = origin; i < keys.length - 1; i++) {
                if (typeof now[keys[i]] != 'object')
                    now[keys[i]] = {};
                now = now[keys[i]];
            }
            delete now[keys[i]];
        })

    }
    return origin;
}

//针对虚拟库存的返回体写的判断方法
function toContain(data, expected) {
    if (typeof expected != 'object') {
        expect('error:the expected type should be Object').toBe(0);
        return false;
    }
    var pass = true;
    if (typeof data != 'object')
        pass = false;
    else {
        if (data.code != expected.code) {
            pass = false;
        }
        else if (expected.result) {
            if (Array.isArray(data.result)) {
                data.result.forEach(function (data) {
                    Object.keys(expected.result).forEach(function (key) {
                        if (JSON.stringify(data[key]) != JSON.stringify(expected.result[key]))
                            pass = false;
                    })
                })
                if (data.result.length == 0)
                    pass = false;
            }
            else Object.keys(expected.result).forEach(function (key) {
                if (JSON.stringify(data.result[key]) != JSON.stringify(expected.result[key]))
                    pass = false;
            })
        }
        if (expected.errMessage && expected.errMessage != data.errMessage) {
            pass = false
        }

    }
    if (!pass) {
        expect('actual: ' + JSON.stringify(data) + '\n expected: ' + JSON.stringify(expected)).toBe(0)
    }
    else {
        expect(0).toBe(0);
    }
    return pass;
}
//基于it的接口调用
function itRequest(url, dataFn, expected, cb) {
    it(url, function (done) {
        var requestBody = dataFn();

        function callback(data) {
            if (typeof cb == 'function') {
                cb(data);
            }
            toContain(data, expected || {code: 0, result: requestBody})
            done()
        }

        sendRequest(callback, {
            url: baseUrl + url,
            data: requestBody
        })
    })
}

//生成对应类型的数据,与方法changeData不同：change只会修改第一层原有key的值，且不会新增
function dataBuilder(model, change, remove) {
    var result = {};
    var id = getUniqueId();
    for (var key in model) {

        if (remove && (remove.indexOf(key) > -1))
            continue;
        var type = model[key]['type'];
        if (change && change[key]) {
            type = change[key]['type'];
        }
        //different type
        if (!type)
            result[key] = '中文e1@';
        else if (type == 'number')
            result[key] = 1234;
        else if (type == 'date') {
            result[key] = new Date(Date.now());
        }
        else if (type == 'object') {
            result[key] = {a: {b: {c: 222}}};
        }
        else if (type == 'boolean')
            result[key] = false;
        else if (typeof type == 'function')
            type(result, dataM);
        else result[key] = type;
        //unique data
        if (model[key]['unique'])
            result[key] += parseInt(id);
    }

    return result;
}
//测试生成方法 数据字段的唯一、必填、类型
function testParams(modelName) {
    var model = models[modelName];
    var modelM = dataM[modelName];
    var requireArr = [];
    var uniqueRequestBodys = {};
    modelM.get(function (result) {
        for (var uniqueKey in uniqueRequestBodys) {
            uniqueRequestBodys[uniqueKey][uniqueKey] = result[uniqueKey];
        }
    }, 'unique');
    Object.keys(model).forEach(function (key) {
        if (model[key]['required']) {
            describe(key + ' required', function () {
                modelM.create(null, null,{code: 1, errMessage: key}, null, [key])
            })
        }
        else  {
            requireArr.push(key);
        }

        if (model[key]['unique']) {
            describe(key + ' unique', function () {
                var change = {};
                change[key] = {
                    type: function (requestBody, dataM) {
                        uniqueRequestBodys[key] = requestBody;
                    }
                }
                modelM.create(null, null, {code: 21, errMessage: key},change)
            })
        }
        if(model[key]['type'] ){
            if( typeof model[key]['type']=='function')
            var errResult ={code:2,errMessage:key};
            describe(key+' type check',function(){
                var change = {};
                change[key] = {type:'just string'}
                modelM.create(null,null,errResult || {code:22,errMessage:key},change);
            })
        }
    })
    describe('other params is not required',function(){
        modelM.create(null,null,null,null,requireArr);
    })
    describe('other params is not unique',function(){//因为不唯一的参数都一样，所以正常请求两次就可以判读
        modelM.create();
        modelM.create();
    })


}
//添加数据管理对象,初始化model的增删改查方法
dataM = (function () {
    var result = {};
    var dataManager = {result: result};
    var indexKey = '_id';
    //遍历所有模型，自动化创建其增删改查
    Object.keys(models).forEach(function (key) {
        var model = models[key];
        dataManager[key] = {};
        urls[key] = urls[key] || {};
        expecteds[key] = expecteds[key] || {};
        result[key] = result[key] || {create: []};
        //定义新增数据it方法
        if (!urls[key]['create'])
            urls[key]['create'] = '/' + key + '/create';
        dataManager[key]['create'] = function (cb, dataFn, expected, change, remove) {
            if (!dataFn) {
                var requestBody = dataBuilder(model, change, remove);
                dataFn = function () {
                    return requestBody;
                };
            }
            var callback = function (data) {
                console.log()
                if (data.code == 0)
                    result[key]['create'].push(data.result);
                cb && cb(data);
            }
            var defaultExpected = expecteds[key] && expecteds[key]['create'];
            itRequest(urls[key]['create'], dataFn, expected || defaultExpected, callback)

        }
        //定义删除数据it方法
        if (!urls[key]['delete'])
            urls[key]['delete'] = '/' + key + '/delete';
        dataManager[key]['delete'] = function (cb, dataFn, expected) {
            var defaultExpected = (expecteds[key] && expecteds[key]['delete']) || {code: 0, result: {n: 1}}
            itRequest(urls[key]['delete'], dataFn, expected || defaultExpected, cb)
        }
        //定义查询数据it方法
        if (!urls[key]['list'])
            urls[key]['list'] = '/' + key + '/list';
        dataManager[key]['list'] = function (cb, dataFn, expected) {
            var defaultExpected = expecteds[key] && expecteds[key]['list'];
            itRequest(urls[key]['list'], dataFn, expected || defaultExpected, cb)
        }
        //定义修改数据it方法
        if (!urls[key]['modify'])
            urls[key]['modify'] = '/' + key + '/modify';
        dataManager[key]['modify'] = function (cb, dataFn, expected) {
            var defaultExpected = expecteds[key] && expecteds[key]['modify'] || {code: 0, result: {n: 1}};
            itRequest(urls[key]['modify'], dataFn, expected || defaultExpected, cb)
        }

        //定义获取数据的方法
        initGet(key, dataManager, result);
    })


//jasmine运行结束后删除所有生成的数据
    var myReporter = {
        jasmineDone: function () {
            console.log('Finished suite');
            console.log(result);
            Object.keys(result).forEach(function (key) {
                result[key]['create'].forEach(function (data) {
                    if (data)
                        sendRequest(function (resData) {
                        }, {url: baseUrl + urls[key]['delete'], data: data})
                })

            })
        },

        specStarted: function (result) {
            console.log(result.fullName);
        }
    };
    jasmine.getEnv().addReporter(myReporter);
    return dataManager;
})()

//所有model自生成的方法说明
var demoDoc = {
    /*cb:function(data){data == {code:n,result:{},errMessage:""},必填；
     dataFn:function(){return requestBody},create方法非必填，其他三个必填；
     change:{key:value},
     remove:[key1,key2],
     expected:{code:n,result:{},errMessage:""}
     */
    create: function (cb, dataFn, expected, change, remove) {
    },
    delete: function (cb, dataFn, expected) {
    },
    list: function (cb, dataFn, expected) {
    },
    modify: function (cb, dataFn, expected) {
    },
    /*cb:function(result){result == {_id:'',....},必填；
     index:你要取的数据集合里面的索引值，默认为'defaultIndex'
     dataType:你要取哪个数据集合，默认为 'normal';
     */
    get: function (cb, index, dataType) {
    }
}


